
# from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
# from psycopg2.extras import execute_values
# import psycopg2
from requests.packages.urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter
import requests
from datetime import datetime
import redis
import json
import re
import os


# def updata_table(cargs, data):
#     connection = psycopg2.connect(**cargs)
#     connection.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
#     connection.autocommit = True
#     cursor = connection.cursor()
#     query = f"""
#         INSERT INTO sentinel2_l1c
#         (name,id,tile,cloud,online,product_date,geom,create_date) 
#         VALUES %s
#         ON CONFLICT (name)
#         DO UPDATE SET 
#         online=excluded.online,
#         id=excluded.id,
#         tile=excluded.tile,
#         cloud=excluded.cloud,
#         product_date=excluded.product_date,
#         geom=excluded.geom,
#         create_date=excluded.create_date;
#         """
#     execute_values(cursor, query, data)
#     cursor.close()
#     connection.close()
#     return


def analysis_product(tile,product):
    product_date = datetime.strptime(
        product['ContentDate']['Start'],"%Y-%m-%dT%H:%M:%S.%fZ")
    wkt = re.search(r"'(.*?)'",product['Footprint']).group(1)
    cloud = list(filter(lambda x:x['Name']=="cloudCover",product['Attributes']))[0]["Value"]
    record = (
        product['Name'].replace(".SAFE",""),
        product['Id'],
        tile,
        cloud,
        product['Online'],
        product_date,
        wkt,
        datetime.now())
    if product['Online']: # 获取在线可下载数据
        ContentDate=datetime.strptime(product['ContentDate']['Start'],"%Y-%m-%dT%H:%M:%S.%fZ")
        params = [
            product['Name'].replace(".SAFE",""),
            ContentDate.strftime("%Y%m%d"),
            product['Id']]
    else:
        params = []
    return record,params


def params_2_query(tile:str,sdate:str,edate:str,cloud:float=100.0):
    url = "https://catalogue.dataspace.copernicus.eu/odata/v1/Products"
    attributes = [
        f"Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'tileId' and att/OData.CSC.StringAttribute/Value eq '{tile}')",
        f"Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'processingLevel' and att/OData.CSC.StringAttribute/Value eq 'S2MSI1C')",#S2MSI1C
        f"Attributes/OData.CSC.DoubleAttribute/any(att:att/Name eq 'cloudCover' and att/OData.CSC.DoubleAttribute/Value lt {cloud})",
        f"ContentDate/Start gt {sdate}T00:00:00.000Z",
        f"ContentDate/Start lt {edate}T00:00:00.000Z"]
    params = {
        '$filter':" and ".join(attributes),
        '$orderby': "ContentDate/Start desc",
        '$count':'True',
        '$expand': 'Attributes'} # Assets Attributes
    return (url,params)


def core(agent:dict,tile:str,sdate:str,edate:str,cloud:float=100.0):
    proxies = {
        'http': f"{agent['host']}:{agent['port']}",
        'https': f"{agent['host']}:{agent['port']}"}
    retries = Retry(
            total=10,
            connect=5,
            read=5,
            backoff_factor=0.5,# 0.5
            raise_on_status=True,
            status_forcelist=[104,500,502,503,504])
    adapter = HTTPAdapter(
        max_retries=retries,
        pool_connections=1,
        pool_maxsize=1)
    session = requests.Session() 
    session.proxies.update(proxies)
    session.mount('http://', adapter)
    session.mount('https://', adapter)
    session.keep_alive = True
    tasks = [params_2_query(tile,sdate,edate,cloud)]
    records = []
    while tasks:
        url,params = tasks.pop()
        try:  # 如果元素b存在则执行查询
            with session.get(url,params=params) as response:
                result = response.json()
                if response.status_code == 200:
                    nextlink = result.get("@odata.nextLink")
                    if nextlink: tasks.append([nextlink,None])
                    for product in result["value"]:
                        record = analysis_product(tile,product)
                        records.append(record)
                else: 
                    print(response.status_code,response.json())
        except requests.RequestException as e: 
            print(e)
    session.close() 
    return records

